import { GObject, UIPackage } from "fairygui-cc";
import { LayerManager } from "../base/LayerManager";
import { LayerType } from "../base/LayerType";
import { ResCache } from "./ResCache";
import ResSetting from "./ResSetting";


export class ResCacheUI extends ResCache {

    private activeDict: { [key: string]: Array<any> } = {};
    private cachesDict: { [key: string]: Array<any> } = {};

    protected loadFinish(asset: any) {
        if (asset) {
            asset[ResSetting.Mark] = this;
        }
        super.loadFinish(asset);
    }

    protected getCachesList(name: string): Array<any> {
        var arr = this.cachesDict[name];
        if (!arr) {
            arr = [];
            this.cachesDict[name] = arr;
        }
        return arr;
    }

    protected getActiveList(name: string): Array<any> {
        var arr = this.activeDict[name];
        if (!arr) {
            arr = [];
            this.activeDict[name] = arr;
        }
        return arr;
    }

    protected onLoadRes() {
        UIPackage.loadPackage(this.path, (error: any, asset: UIPackage) => {
            if (error) {
                console.error(`加载FGUI失败：${this.path}`);
                console.error(error);
            }
            this.loadFinish(asset);
        });
    }

    public release() {
        for (let key in this.activeDict) {
            let arr = this.activeDict[key];
            for (let i = 0; i < arr.length; ++i) {
                arr[i].dispose();
            }
            arr.splice(0, arr.length);
        }

        for (let key in this.cachesDict) {
            let arr = this.cachesDict[key];
            for (let i = 0; i < arr.length; ++i) {
                arr[i].dispose();
            }
            arr.splice(0, arr.length);
        }
        UIPackage.removePackage(this.path);

    }

    public spawn(name: string): any {
        let caches = this.getCachesList(name);
        let obj = null;
        if (caches.length > 0) {
            let idx = caches.length - 1;
            obj = caches.splice(idx, 1)[0];
        }
        else {
            try {
                let asset = UIPackage.getById(this.path);
                obj = asset?.createObject(name);
            } catch (error) {
                console.error(error);
            }
        }

        if (!obj) {
            console.error(`创建UI界面失败: path=${this.path} name=${name}`);
            return null;
        }

        obj[ResSetting.Mark] = this;
        obj['_resName'] = name;
        let actives = this.getActiveList(name);
        actives.push(obj);
        this.ref++;
        this.tick = Date.now();
        return obj;
    }

    public unSpawn(obj?: any) {
        if (!obj[ResSetting.Mark]) {
            console.error(`回收资源有误，资源已经被回收 asset=${this.path} name=${obj.name}`);
            return;
        }

        let name = obj['_resName'];
        let actives = this.getActiveList(name);
        let idx = actives.indexOf(obj);
        if (idx != -1)
            actives.splice(idx, 1);

        let caches = this.getCachesList(name);
        caches.push(obj);
        LayerManager.inst.setLayer(obj, LayerType.UI_Res);
        this.ref--;
        this.tick = Date.now();
        obj[ResSetting.Mark] = null;
    }

    public unSpawnAll(name: string) {
        let actives = this.getActiveList(name);
        let caches = this.getCachesList(name);
        for (let i = 0; i < actives.length; ++i) {
            let obj = actives[i];
            if (!obj[ResSetting.Mark]) {
                console.error(`回收资源有误，资源已经被回收 asset=${this.path} name=${name}`);
                continue;
            }
            obj[ResSetting.Mark] = null;
            LayerManager.inst.setLayer(obj, LayerType.UI_Res);
            caches.push(obj);
            this.ref--;
        }
        actives.splice(0, actives.length);
        this.tick = Date.now();
    }

    /**
     * 资源是否有效
     */
    protected isValid(): boolean {
        return UIPackage.getById(this.path) != null;
    }
}